package com.niiwoo.civet.account.service.dubbo;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.rpc.RpcContext;
import com.niiwoo.activity.stage.dto.response.prize.SendOrderDetailRespDTO;
import com.niiwoo.civet.account.dao.entity.ActivityOrder;
import com.niiwoo.civet.account.dto.common.MarketingDTO;
import com.niiwoo.civet.account.dto.request.MarketingDubboRequestDTO;
import com.niiwoo.civet.account.dto.response.ActivityOrderRespDTO;
import com.niiwoo.civet.account.enums.AccountSendPrizeStatusEnum;
import com.niiwoo.civet.account.service.MarketingAsyncDubboService;
import com.niiwoo.civet.account.service.MarketingDubboService;
import com.niiwoo.civet.account.service.local.MarketingLocalService;
import com.niiwoo.tripod.lanmao.enums.UserRoleEnum;
import com.niiwoo.tripod.provider.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * @Description
 * @Author zq
 * @Date 2017/12/2
 */
@Slf4j
@Service(version = "1.0.0", validation = "true")
public class MarketingDubboServiceImpl implements MarketingDubboService {

    @Autowired
    MarketingLocalService marketingLocalService;

    @Reference(version = "1.0.0")
    private MarketingAsyncDubboService marketingAsyncDubboService;

    @Override
    public void sendCashPrize(MarketingDubboRequestDTO requestDTO) throws BizException, ExecutionException, InterruptedException {
        Assert.notNull(requestDTO, "发送红包不可为空");
        Assert.notNull(requestDTO.getUserId(), "用户ID不可为空");
        Assert.notNull(requestDTO.getOrderNo(), "订单不可为空");
        Assert.notNull(requestDTO.getUserRoleEnum(), "账户类型不可为空");
        Assert.notNull(requestDTO.getPrizeTypeIdEnum(), "红包类型不可为空");
        Assert.notNull(requestDTO.getExtendTypeEnum(), "红包子账单类型不可为空");
        Assert.notNull(requestDTO.getSourceTypeEnum(), "红包来源不可为空");
        ActivityOrder order = marketingLocalService.addSendCashOrder(requestDTO);
        boolean asyncFlag = marketingLocalService.asyncSendTransaction(order.getRequestNo(), requestDTO.getUserRoleEnum());

        AccountSendPrizeStatusEnum sendPrizeStatusEnum = asyncFlag ? AccountSendPrizeStatusEnum.SEND : AccountSendPrizeStatusEnum.SEND_FAILED;
        marketingLocalService.activityOrderStatusChange(order.getRequestNo(), sendPrizeStatusEnum);
        // 回调统一内部判断
        marketingLocalService.asyncCall(order.getRequestNo(), sendPrizeStatusEnum);

    }

    @Override
    public void callCashPrize(MarketingDTO marketingDTO) {
        if (AccountSendPrizeStatusEnum.SEND_SUCCESS.getValue().equals(marketingDTO.getSendPrizeStatusEnum().getValue())) {
            SendOrderDetailRespDTO responseDTO = marketingLocalService.getPrizeDescription(marketingDTO.getAsyncRequestNo());
            marketingLocalService.successAsyncTransaction(marketingDTO.getAsyncRequestNo(), responseDTO);
        } else {
            marketingLocalService.failedAsyncTransaction(marketingDTO.getAsyncRequestNo());
        }
        // 回调统一内部判断
        marketingLocalService.asyncCall(marketingDTO.getAsyncRequestNo(), marketingDTO.getSendPrizeStatusEnum());
    }

    @Override
    public void resendPrize() {
        marketingLocalService.resendPrize();
    }

    @Override
    public ActivityOrderRespDTO saveCashPrizeAndAsyncSend(MarketingDubboRequestDTO requestDTO) throws BizException, ExecutionException, InterruptedException {
        Assert.notNull(requestDTO, "发送红包不可为空");
        Assert.notNull(requestDTO.getUserId(), "用户ID不可为空");
        Assert.notNull(requestDTO.getOrderNo(), "订单不可为空");
        Assert.notNull(requestDTO.getUserRoleEnum(), "账户类型不可为空");
        Assert.notNull(requestDTO.getPrizeTypeIdEnum(), "红包类型不可为空");
        Assert.notNull(requestDTO.getExtendTypeEnum(), "红包子账单类型不可为空");
        Assert.notNull(requestDTO.getSourceTypeEnum(), "红包来源不可为空");
        ActivityOrder order = marketingLocalService.addSendCashOrder(requestDTO);

        final String requestNo = order.getRequestNo();
        UserRoleEnum userRoleEnum = requestDTO.getUserRoleEnum();


        RpcContext.getContext().asyncCall(() -> {
            try {
                marketingAsyncDubboService.sendPrize(requestNo, userRoleEnum);
            } catch (ExecutionException e) {
                log.error("saveCashPrizeAndAsyncSend asyncCall is error:", e);
            } catch (InterruptedException e) {
                log.error("saveCashPrizeAndAsyncSend asyncCall is error:", e);
            }
        });

        ActivityOrderRespDTO respDTO = new ActivityOrderRespDTO();
        BeanUtils.copyProperties(order, respDTO);
        return respDTO;
    }

    @Override
    public ActivityOrderRespDTO querySendCashPrizeInfo(Long orderNo) {
        return marketingLocalService.querySendCashPrizeInfo(orderNo);
    }

    @Override
    public ActivityOrderRespDTO queryActivityOrderByRequestNo(String requestNo) {
        ActivityOrder activityOrder = marketingLocalService.getActivityOrderByRequestNo(requestNo);
        ActivityOrderRespDTO activityOrderRespDTO = null;
        if (null != activityOrder) {
            activityOrderRespDTO = new ActivityOrderRespDTO();
            BeanUtils.copyProperties(activityOrder, activityOrderRespDTO);
        }
        return activityOrderRespDTO;
    }

    @Override
    public void queryTransactionPrize() {
        marketingLocalService.queryTransactionPrize();
    }


}
